  /**
  *  IMPORTANT NOTE!
  *  The symbol VECT_TAB_SRAM needs to be defined when building the project
  *  if code has been located to RAM and interrupts are used. 
  *  Otherwise the interrupt table located in flash will be used.
  *  See also the <system_*.c> file and how the SystemInit() function updates 
  *  SCB->VTOR register.  
  *  E.g.  SCB->VTOR = 0x20000000;  
  */

// Advanced High-performance Bus = AHB
// ? Advanced Peripheral Bus = APB ?

#include <stdio.h>
#include "stm32f4xx.h"
#include "commands_4bits.h"
#include "stm32f4xx_usart.h"


void delai(void)
{
        int i;
        for(i=0; i < 1000000; i++)
        ;
}

// Voir document User Manual DM00031020.pdf
int main(void)
{
        int i;
//  printf("Test"); // BLOQUE !
         // GPIOD Periph clock enable
         RCC->AHB1ENR   |= RCC_AHB1ENR_GPIODEN ;
         RCC->AHB1LPENR |= RCC_AHB1LPENR_GPIODLPEN;
         // Leds : Orange sur PD13, verte sur PD12, Rouge sur PD14, Bleu sur PD14
         // On met tout le port D en GENERAL PURPOSE OUTPUT -> 0b01010101010101010101010101010101
         GPIOD->MODER   = 0x55555555;   // voir L654 stm32f4xx.h
         GPIOD->OTYPER  = 0x00000000;   // OUTPUT TYPE REGISTER Push Pull
         GPIOD->OSPEEDR = 0xffffffff;   // 100 MHz
         GPIOD->PUPDR   = 0x00000000;   // No Pull up, No Pull Down

         // GPIOC Periph clock enable
         RCC->AHB1ENR   |= RCC_AHB1ENR_GPIOCEN ;
         RCC->AHB1LPENR |= RCC_AHB1LPENR_GPIOCLPEN;
         GPIOC->MODER   = 0x55555555;   // voir L654 stm32f4xx.h
         GPIOC->OTYPER  = 0x00000000;   // OUTPUT TYPE REGISTER Push Pull
         GPIOC->OSPEEDR = 0xffffffff;           // 100 MHz
         GPIOC->PUPDR   = 0x00000000;   // No Pull up, No Pull Down

         // GPIOB Periph clock enable
         RCC->AHB1ENR   |= RCC_AHB1ENR_GPIOBEN ;
         RCC->AHB1LPENR |= RCC_AHB1LPENR_GPIOBLPEN;
         GPIOB->MODER   = 0x55555555;   // voir L654 stm32f4xx.h
         GPIOB->OTYPER  = 0x00000000;   // OUTPUT TYPE REGISTER Push Pull
         GPIOB->OSPEEDR = 0xffffffff;           // 100 MHz
         GPIOB->PUPDR   = 0x00000000;   // No Pull up, No Pull Down


        // !!!! il faut le laisser le temps a l'achiffeur du 20eme siecle de demarrer
        delai();
        delai();
        delai();
        //init_old();
        lcd_init();
        clear_display();
        write_char('S');
        write_char('T');
        write_char('M');
        write_char('3');
        write_char('2');
        write_char('F');
        write_char('4');
        write_char('0');
        write_char('7');
        write_char('V');
        write_char('G');
        write_char('T');
        write_char('6');
        write_char('-');
     /*   line_feed();
        write_char('U');
        write_char('S');
        write_char('A');
        write_char('R');
        write_char('T');
        write_char('2');
        write_char(' ');
        write_char('D');
        write_char('E');
        write_char('M');
        write_char('O');
       */
        for(i=0; i < 40; i++)
          delai();


        // GPIOA Periph clock enable
/*      RCC->AHB1ENR   |= RCC_AHB1ENR_GPIOAEN ;
        RCC->AHB1LPENR |= RCC_AHB1LPENR_GPIOALPEN;
        GPIOA->MODER   = 0x55555555;   // voir L654 stm32f4xx.h
        GPIOA->OTYPER  = 0x00000000;   // OUTPUT TYPE REGISTER Push Pull
        GPIOA->OSPEEDR = 0xffffffff;           // 100 MHz
        GPIOA->PUPDR   = 0x00000000;   // No Pull up, No Pull Down
*/
         // APB1 Prescaler=4 par default
         // PORT A -> UART2 PA2=USART2_TX, PA3=USART2_RX
         // Reset and Clock Control (RCC)
         // RCC APB1 Periph. CLK Enable Reg.
         RCC->APB1ENR |= RCC_APB1ENR_USART2EN;   // p113
         // RCC AHB1 Periph. CLK Enable Reg.
         RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;    // p112
         //RCC->AHB1LPENR |= RCC_AHB1LPENR_GPIOALPEN;
         // Alternate Function for UART
         int alternatefunction = 0x2;
         GPIOA->MODER   |= ((alternatefunction<<6)|(alternatefunction<<4)); // p148 Alt. Func. pour PA3 & PA2
         //GPIOA->MODER 	= 0xAAAAAAAA; 	// Alternate function pour tout le portA
         //GPIOA->MODER 	= 0x55555555; 	// General Output Marche pas pour Uart
         GPIOA->OTYPER  = 0x00000000;   // Push Pull pout tout le portA
         GPIOA->OSPEEDR = 0xAAAAAAAA;  // 50 MHz  //0x55555555;   // 25 MHz
         GPIOA->PUPDR   = 0x55555555; //0xAAAAAAAA; Pull Down //0x55555555;   // Pull up
         // Alternate Function AF7 (USART1..3)
         int AF7 = 7; // 0b0111
         GPIOA->AFR[0]	|= ((AF7<<12)|(AF7<<8)); // AF7 pour PA3 & PA2
         //GPIOA->AFR[0] = 0x77777777;  // Tout le portA
         //GPIOA->AFR[1] = 0x77777777;  // Tout le PortA

         // Calcul USARTDIV pour un Baud Rate de 9600
         // 1. si CLK = 168000000 [Hz]
         // 2. si APB1 Prescaler = 4 -> PCLK = 42000000 [Hz] (USART2 sur APB1)
         // 3. si 9600 bauds =>  9600 = 420000000/(8*(2-OVER8)*USARTDIV)
         // 4. si OVER8 = 0 (valeur par defaut au reset)
         // 5. -> USARTDIV = 420000000/(16*9600) = 273.4375
         // 6.->  Mantisse = 273 (bit 4 a 15 de USARTx->BRR)
         // 7. -> Fraction = 0.4375*16 = 7 (bit 0 a 3 de USARTx->BRR)
         USART2->BRR = (273<<4)+7;
         // CR1
         USART2->CR1 = 0;
         USART2->CR1 |= (0<<15);		// bit15 = Oversampling 16
         // bit14 reserved
         USART2->CR1 |= (1<<13);		// bit13 = USART enable
         USART2->CR1 |= (0<<12);		// bit12 : 1 Start bit, 8 Data bits, n Stop bit
         // bit11 = WAKE
         USART2->CR1 |= (0<<10);		// bit10 : 1 = Parity Enable, 0 = Parity Disable
         // bit9 = PARITY Selection 1 = Odd, 0 = Even
         // bit8 PEIE Int.
         // bit7 TXEIE Int.
         // bit6 TCIE Int.
         // bit5 RXNEIE Int.
         // bit4 IDLEIE Int.
         USART2->CR1 |= (1<<3)|(1<<2);	// bit3&2 : TX, RX enable
         // bit1 RWU: Receiver wakeup
         // bit0 SBK: Send break

         // CR2
         USART2->CR2 = 0;
         // bit14 LINEN LIN mode enable
         USART2->CR2 |= ((0<<13)|(0<<12));		// bit13&12 : Stop Bits 00=1sb, 01=0.5sb, 10=2sb, 11=1.5sb
         // bit11 CLKEN: Clock enable
         // bit10 CPOL: Clock polarity
         // bit9  CPHA: Clock phase
         // bit8 LBCL: Last bit clock pulse
         // bit7 Reserved, must be kept at reset value
         // bit6 LBDIE: LIN break detection interrupt enable
         // bit5 LBDL: lin break detection length
         // bit4 Reserved, must be kept at reset value
         // bits3:0 ADD[3:0]: Address of the USART node

         // CR3
         USART2->CR3 = 0;
         // bit11 ONEBIT: One sample bit method enable 1 = One bit SAmpling, 0 = three bits sampling
         // bit10 CTSIE: CTS interrupt enable
         // bit9 CTSE: CTS enable,  0 = no hard flow control
         // bit8 RTSE: RTS enable,  0= no hard flow control
         // bit7 DMAT: DMA enable transmitter
         // bit6 DMAR: DMA enable receiver
         // bit5 SCEN: Smartcard mode enable
         // bit4 NACK: Smartcard NACK enable
         // bit3 HDSEL: Half-duplex selection
         // bit2 IRLP: IrDA low-power
         // bit1 IREN: IrDA mode enable
         // bit0 EIE: Error interrupt enable


        while(1)
        {
  //      	printf("UART\n");
            cursor_home();
            clear_display();
            delai();
            write_char('-');
            write_char('>');
            for(i=0; i < 10; i++)
                         delai();

            // UART Transmision
            char ch = 65;
            //while (!(USART2->SR & (1<<7)));
             USART2->DR = (ch & 0xFF);
              while( (USART2->SR & (1<<6)) ==  0 ) // bit6 = 0 tant que transmission incomplete
              //while (!(USART2->SR & (1<<7))); // bit7 = 1 tant que transfert dans le shift register
            ch = 66;
             USART2->DR = (ch & 0xFF);
              while( (USART2->SR & (1<<6)) ==  0 ) // bit6 = 0 tant que transmission incomplete
            ch = 67;
             USART2->DR = (ch & 0xFF);
              while( (USART2->SR & (1<<6)) ==  0 ) // bit6 = 0 tant que transmission incomplete



            /* ch = 0x55;
             //while (!(USART2->SR & (1<<7)));
             USART2->DR = (ch & 0xFF);
              while (!(USART2->SR & (1<<7)));
            */
/*
         // ON
         //Tous les bits d'un coup : GPIOD->ODR = 0x0000f000;
         GPIOD->BSRRL = 1<<12;  // Led VERTE sur PD12
         GPIOD->BSRRL = 1<<13;  // Led ORANGE sur PD13
         GPIOD->BSRRL = 1<<14;  // Led ROUGE sur PD14
         GPIOD->BSRRL = 1<<15;  // Led BLEUE sur PD15
         // Channel 1 sur IKALOGIC
         GPIOD->BSRRL = 1;
         GPIOD->BSRRH = 2;
         delai();
         // OFF
         GPIOD->BSRRH = 1<<12;  // Led VERTE sur PD12
         GPIOD->BSRRH = 1<<13;  // Led ORANGE sur PD13
         GPIOD->BSRRH = 1<<14;  // Led ROUGE sur PD14
        // GPIOD->BSRRH = 1<<15;  // Led BLEUE sur PD15
         GPIOD->BSRRH = 1;
         GPIOD->BSRRL = 2;
*/

    cursor_home();
    clear_display();
   // for(i=0; i < 20; i++)
                 delai();
    write_char('O');
    write_char('K');
    for(i=0; i < 10; i++)
                 delai();
  }


}

/*
// http://www.micromouseonline.com/2009/12/31/stm32-usart-basics/?doing_wp_cron=1349023988.8915889263153076171875#axzz27yNXXhGG
void usartSetup (void)
{
  // make sure the relevant pins are appropriately set up.

  RCC_APB2ENR |= RCC_APB2ENR_IOPAEN;              // enable clock for GPIOA
  GPIOA_CRH   |= (0x0BUL  << 4);                  // Tx (PA9) alt. out push-pull
  GPIOA_CRH   |= (0x04UL  << 8);                  // Rx (PA10) in floating
  RCC_APB2ENR |= RCC_APB2ENR_USART1EN;            // enable clock for USART1
  USART1_BRR  = 64000000L/115200L;                // set baudrate
  USART1_CR1 |= (USART1_CR1_RE | USART1_CR1_TE);  // RX, TX enable
  USART1_CR1 |= USART1_CR1_UE;                    // USART enable
}
int SendChar (int ch)
{
  while (!(USART1_SR & USART1_SR_TXE));
  USART1_DR = (ch & 0xFF);
  return (ch);
}
int GetChar (void)
{
  while (!(USART1_SR & USART1_SR_RXNE));
  return ((int)(USART1_DR & 0xFF));
}
// Read more: http://www.micromouseonline.com/2009/12/31/stm32-usart-basics/#ixzz27yRfGaIz
*/

